import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { Position, useReactFlow, Node } from '@xyflow/react';
import { Card, Modal, Spin } from 'antd';
import Subtitle from '../../components/Subtitle';
import useSelectBorder from '../../store/useSceneData';
import CodeMirror from '@uiw/react-codemirror';
import { javascript } from '@codemirror/lang-javascript';
import CustomHandle from '../CustomHandle';
import { Loading3QuartersOutlined } from '@ant-design/icons';
import NodeOperation from '../../components/NodeOperation';
import EditTable, { DataSourceKeys } from '../../components/EditTable'
import useInitVariable from '@/hooks/useInitVariable';

/**
 * 流程节点
 * @param param0 
 * @returns 
 */
const defaultCode = `//query请求数据,result是返回数据
function run({query, result}) {
  return null;
}`

function CodeNode({ id, data }: Node) {
  const { setNodes, setCenter } = useReactFlow();
  const { select, setSelectId, debug, setDeBug } = useSelectBorder()
  const [code, setCode] = useState(data.code || defaultCode);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const dataSource = useRef<DataSourceKeys>(data.codeParams as DataSourceKeys || {
    "dataSource": [
      {
        "id": 0,
        "label": "query",
        "value": "sys.query"
      },
      {
        "id": 1,
        "label": "result",
        "value": "sys.result"
      }
    ],
    "editableKeys": []
  });
  const { initSetVariable } = useInitVariable()

  const handleFocus = () => {
    setSelectId(id);
    setDeBug(false)
  };

  useEffect(() => {
    if (isModalOpen) {
      data.code && setCode(data.code)
    }
  }, [isModalOpen])

  const onChange = useCallback((val) => {
    setCode(val);
  }, []);

  useEffect(() => {
    if (select[id] && debug) {
      setNodes((nodes: Node[]) => {
        const node = nodes.find(node => node.id == id)
        setCenter(node.position.x + 200, node.position.y, { zoom: 1, duration: 500 })
        return [...nodes];
      })
    }
  }, [select[id]])

  useEffect(() => {
    initSetVariable(data.title as string || "代码运行", id)

    if (!data.codeParams) {
      setNodes((nodes) => {
        const node = nodes.find(node => node.id == id)
        node.data.code = code
        node.data.codeParams = dataSource.current
        return [...nodes]
      })
    }
  }, [])

  return (
    <NodeOperation nodeId={id} onClick={() => setIsModalOpen(true)}>
      <Card
        title={<div className='flex'>
          <Subtitle imgUrl='img/code.png'
            title={data.title as string || "代码"} id={id}
            onBlur={(title) => initSetVariable(title, id)} />
          {select[id] && debug && <Spin indicator={<Loading3QuartersOutlined spin />} className='mt-[6px] ml-2' />}
        </div>}
        style={{
          outline: select[id] ? "2px solid #145FF0" : "none",
          width: 310,
          zIndex: select[id] ? 1000 : 1
        }}
        onClick={handleFocus}
        tabIndex={0}
      >
        <CustomHandle count={2} type="target" position={Position.Left} id="codeStart" style={{ background: '#2970ff', top: 74 }} />
        <Modal title={<span>{data.title as string || '代码执行'}</span>}
          open={isModalOpen}
          destroyOnClose={true}
          footer={false}
          onCancel={() => {
            setNodes((nodes) => {
              const node = nodes.find(node => node.id == id)
              node.data.code = code
              dataSource.current.dataSource = dataSource.current.dataSource.filter(item => item.label)
              node.data.codeParams = dataSource.current
              return [...nodes]
            })
            setIsModalOpen(false)
          }}>

          {/** 变量编辑 */}
          <EditTable
            value={data.codeParams as DataSourceKeys || dataSource.current}
            onChange={(editData) => dataSource.current = editData}
          />

          {/** 代码编辑 */}
          <CodeMirror value={code as string}
            height="300px"
            style={{ border: '1px solid #f0f0f0', borderRadius: 12, overflow: 'hidden' }}
            placeholder="请输入js代码"
            defaultValue={"function"}
            extensions={[javascript({ jsx: true })]}
            onChange={onChange} />

        </Modal>
        <CustomHandle count={1} type="source" position={Position.Right} id="codeIf" style={{ top: 74 }} />
      </Card>
    </NodeOperation>
  );
}

export default memo(CodeNode)